from scipy import isnan,median,histogram,cumsum,array,Inf,arange,shape,ones,nan
from pylab import clim,gca,clf,gci,figtext,rcParams,grid,find,savefig,gcf,axes,imshow,figure,axes,imread
import pylab
from matplotlib import colors 
from os import getcwd
def autoclim(conf=.95, I=None):
  I = array(gci().get_array()) if I is None else I
  clim(getclim(I,conf=conf))


def getclim( I, conf=.95,):
  I=I[~isnan(I)]
  H=histogram(I[(I<Inf)*(I>-Inf)].ravel(),bins=100)
  mI=median(I)
  median_nI = find(mI<H[1])[0]
  if len(H[0][median_nI:])==0:
    Cl2=H[1][-1]
  else:
    f1  = find(cumsum(H[0][median_nI:])>(sum(H[0][median_nI:])*conf))
    Cl2 = H[1][median_nI:][f1[0]  if len(f1)>0 else 0]
  if len(H[0][median_nI-1:0:-1])==0:
    Cl1 = H[1][0]
  else:
    f1  = find(cumsum(H[0][median_nI-1:0:-1])>(sum(H[0][median_nI-1:0:-1])*conf))
    Cl1 = H[1][median_nI-1:0:-1][f1[0]  if len(f1)>0 else 0]
  return (Cl1,Cl2)



def setlinesprop(scheme=1,Lines=['-','--','-.',':'],Colors=['k','b','g','r','c','m','y'],ic=0,ils=0,lw=1):
  ax = gca()  
  for i,line in enumerate(ax.lines):
    if scheme == 1:
      ils = i%len(Lines)
    elif scheme == 2:
      ic = i%len(Colors)
      ils = i%len(Lines)
    elif scheme == 3:
      ic = i%len(Colors)
    line.set_linestyle(Lines[ils])
    line.set_color(Colors[ic])
    line.set_linewidth(lw)

def figtoarticle(nr,hight=2.4):
  image_width=array([8.3,17.1])/2.54 # inches RCS
  image_width=array([3.25,7]) # inches ACS
  rcParams['font.size']=7.0
  rcParams['legend.fontsize']=7.0
  rcParams['savefig.dpi']=600
  rcParams['lines.color']='black'
  figure(nr,figsize=(image_width[0], hight), dpi=140)
  clf()
  axes([0.15,0.14,0.80,0.80])

def yautoscale():
  ax=gca()
  limX=xlim()
  yvals = lambda line: line.get_ydata()[(line.get_xdata()>limX[0])*(line.get_xdata()<limX[1])]
  ylim(min(map(lambda line : yvals(line).min(),ax.lines)),max(map(lambda line : yvals(line).max(),ax.lines)))

def mysciscale():
  ax = gca() 
  x = (ax.get_position().x1 if ax.yaxis.get_label_position() == 'right' else ax.get_position().x0)-0.00,ax.get_position().y1+0.01
  y = (ax.get_position().x1 if ax.yaxis.get_label_position() == 'right' else ax.get_position().x0)-0.00,ax.get_position().y1+0.01
  if (abs(ax.yaxis.get_ticklocs()).max()>10**rcParams['axes.formatter.limits'][1] ):
    n=(len("%i" % abs(ax.yaxis.get_ticklocs()).max()))-1
    ax.yaxis.set_ticklabels(map(lambda x: ("%s" % x).replace(",","."),ax.yaxis.get_ticklocs()*10**-n))
    figtext(x[0],x[1],r"$\times 10^{%s}$" % n)
  if (abs(ax.yaxis.get_ticklocs()).max()<10**rcParams['axes.formatter.limits'][0] ):
    n=(len("%i" % (1./max(abs(ax.yaxis.get_ticklocs())).max())))
    ax.yaxis.set_ticklabels(map(lambda x: ("%s" % x).replace(",","."),ax.yaxis.get_ticklocs()*10**n))
    figtext(y[0],y[1],r"$\times 10^{%s}$" % -n)
  grid(True)
  return x,y


#def mysciscale():
  #ax = gca()  
  #if (abs(ax.yaxis.get_ticklocs()).max()>10**rcParams['axes.formatter.limits'][1] ):
    #n=(len("%i" % abs(ax.yaxis.get_ticklocs()).max()))-1
    #ax.yaxis.set_ticklabels(map(lambda x: ("%s" % x).replace(",","."),ax.yaxis.get_ticklocs()*10**-n))
    #figtext((ax.get_position().x1 if ax.yaxis.get_label_position() == 'right' else ax.get_position().x0)-0.05,ax.get_position().y1+0.01,r"$\times 10^{%s}$" % n)
  #if (abs(ax.yaxis.get_ticklocs()).max()<10**rcParams['axes.formatter.limits'][0] ):
    #n=(len("%i" % (1./min(ax.yaxis.get_ticklocs()).max())))-1
    #ax.yaxis.set_ticklabels(map(lambda x: ("%s" % x).replace(",","."),ax.yaxis.get_ticklocs()*10**n))
    #figtext((ax.get_position().x1 if ax.yaxis.get_label_position() == 'right' else ax.get_position().x0)-0.05,ax.get_position().y1+0.01,r"$\times 10^{%s}$" % -n)
  #grid(True)


def ylim(*ka,**kw):
  test=pylab.ylim(*ka,**kw)
  x,y = mysciscale()
  delt=[]
  for i,t in enumerate(gcf().texts):
    if t.get_text()[:11]== '$\\times 10^' and ((x==t.get_position()) or (y==t.get_position())):
      delt.append(i)
  for i in delt[::-1]:
    del(gcf().texts[i])
  mysciscale()
  return test


def aligntwoyaxes(axe=None):
  if axe is None:
    f = gcf()
    axe = gcf().axes
  dY=[];  lim=[];  zero=[];  limX = xlim()
  yvals = lambda line: line.get_ydata()[(line.get_xdata()>limX[0])*(line.get_xdata()<limX[1])]
  for ax in axe:
    dY.append(ax.yaxis.get_ticklocs()[1]-ax.yaxis.get_ticklocs()[0])    
    lim.append([nanmin(map(lambda line : nanmin(yvals(line)),ax.lines)),nanmax(map(lambda line : nanmax(yvals(line)),ax.lines))])#x.yaxis.get_view_interval())
    zero.append(filter(lambda loc:ax.yaxis.get_view_interval()[0]>=loc ,ax.yaxis.get_ticklocs())[-1])
  n = abs(max([ceil((lim[i][1]-zero[i])/dY[i]) for i in range(len(zero))]))
  for i,ax in enumerate(axe):
    pylab.setp(ax, 'ylim', [zero[i],zero[i]+dY[i]*n])



def mysavefig(folder,endname,basefolder="results/",**kw):
  import commands
  from os.path import isdir
  fol =  folder[8:] if folder.count('rawdata/') else folder
  fol =  folder[len(basefolder):] if folder.count(basefolder) else folder
  j=0;cont=True
  tf=basefolder[:-1]
  for f in fol.split('/')[:]:
    if len(f)>0:
      tf += "/" + f
      if (isdir(tf)==False):
        v=commands.getstatusoutput("mkdir %s" % tf)
  savefig('%s/%s/%s.png' % (basefolder,fol,endname),**kw)
  savefig('%s/%s/%s.pdf' % (basefolder,fol,endname),**kw)

def plotim(imfile):
  try:
    A=pylab.imread(imfile)
  except IOError:
    print "\n##############################\nERROR\n%s not found\n dir is: %s\n##############################" % (imfile,getcwd)
    A=scipy.zeros((9,9))
  pylab.imshow(A);pylab.gca().xaxis.set_visible (False);pylab.gca().yaxis.set_visible (False);pylab.draw()

def plotims(IM,X0=.2,Y0=1.0,cut=(None,None),transp=True,dofigtext=True,scale=1,basename='results/'):
  IM=array(IM)
  if basename[0]<>'/':
    basename=getcwd()+'/'+basename
  ImA=[]
  command = ""
  latexfigure="\\begin{tikzpicture}[anchor=north west]\n"
  filenames = []
  getfilename = lambda S: S[::-1][:S[::-1].find('/')][::-1]
  for row in IM:
    ImA.append([])
    for col in row:
      command += "ln %s.pdf ./\n" % (basename + col[:-4])
      imtmp=imread(basename +col)  
      ImA[-1].append(imtmp[(arange(shape(imtmp)[0]) if cut[0] is None else cut[0]), :,:][:,(arange(shape(imtmp)[1]) if cut[1] is None else cut[1]),:])
  S=array(map(lambda x: map(shape,x),ImA))
  Highs=S[:,:,0].max(1)
  Width=S[:,:,1].max(0)
  newIM = ones((sum(Highs),sum(Width),4))
  newIM[:]=nan
  let = ['A','B','C','D','E','F','G','H']
  H,W,t = map(float,newIM.shape)
  for i,row in enumerate(ImA):
    y0 = Highs.cumsum()[i-1] if i<>0 else 0
    for j,col in enumerate(row):
      #y0,x0 = Highs.cumsum()[i]-Highs[0],Width.cumsum()[j]-Width[0]
      x0 = Width.cumsum()[j-1] if j<>0 else 0
      latexfigure +=  "\\node at (%.3f\\linewidth,%.3f\\linewidth) {\\includegraphics[width=%.3f\\linewidth]{%s.pdf}};\n" % (x0/W,-y0/W,col.shape[1]/W,getfilename(IM[i,j])[:-4])
      newIM[y0:y0+shape(col)[0],x0:x0+shape(col)[1],:]=col
  if transp:
    newIM[((newIM[:,:,0]==1)*(newIM[:,:,1]==1)*(newIM[:,:,2]==1)),3]=0
  figure(figsize=(scale*shape(newIM)[1]/150.,scale*shape(newIM)[0]/150.),dpi=150,frameon=False)
  clf();axes([0,0,1,1],frame_on=False);imshow(newIM,aspect='auto');ax=gca();ax.yaxis.set_visible(False);ax.xaxis.set_visible(False);#ax.set_axis_bgcolor(None)
  I,J=map(float,IM.shape)
  if dofigtext:
    for i,row in enumerate(ImA):
      for j,col in enumerate(row):
        y0,x0 = Highs.cumsum()[i-1] if i<>0 else 0,Width.cumsum()[j-1] if j<>0 else 0
        xp = (x0+X0*col.shape[1])/W
        #figtext(X0/J+1.*j/J,Y0/I+(I-i-1)*1./I,let[int(i*J+j)])
        figtext(xp,1-(y0+(1-Y0)*col.shape[0])/H,let[int(i*J+j)],ha='left',va='top')
        latexfigure +=  "\\node at (%.3f\\linewidth,%.3f\\linewidth) {%s};" %(xp,-(y0+(1-Y0)*col.shape[0])/W , let[int(i*J+j)])
  latexfigure +=   "\\end{tikzpicture}"
  return latexfigure,command

def plotIMs(Figs,width=20/4.):
  aspect = array(map(lambda x: x[0],Figs))
  F = map(lambda x: x[1],Figs)
  figure(figsize=[ width,  width*sum(aspect)])
  cumsumaspect=aspect.cumsum()
  for a,ca,f in zip(aspect,cumsumaspect,F):
    axes([0.0,1-ca/sum(aspect),1.0,a/sum(aspect)])
    if f is not None:
      plotim(f)
      
cdict = {'red': ((0.0, 1.0, 1.0),
                 (0.4, 0.0, 0.0),
                 (0.85, 1.0, 1.0),
                 (1.0, 0.0, 0.0)),
         'green': ((0.0, 1.0, 1.0),
                   (0.9, 0.0, 0.0),
                 (1.0, 0.0, 0.0)),
         'blue': ((0.0, 1.0, 1.0),
                 (0.4, 1.0, 1.0),
                  (.9, 0.0, 0.0),
                 (1.0, 0.0, 0.0))}
my_cmap = colors.LinearSegmentedColormap('my_colormap',cdict,256)